package com.wyj.service.imp;

import com.wyj.pojo.User;
import com.wyj.service.FollowService;
import com.wyj.util.RedisKeyUtil;
import com.wyj.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author 王永杰
 * @Description 描述该类的做什么用
 * @since 2022/7/28
 */
@Service
public class FollowServiceImp implements FollowService {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    UserServiceImp userServiceImp;


    @Override
    public void followee(int userId, int entityType, int entityId) {
        //点击关注的时候 userId用户的关注列表多了一个人
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
        //entityId 用户的粉丝列表多了一个粉丝
        String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);

        redisUtil.multi();

        //将值存进缓存当中
        redisUtil.zAdd(followeeKey, entityId, (double) System.currentTimeMillis());
        redisUtil.zAdd(followerKey, userId, (double) System.currentTimeMillis());

        redisUtil.exec();
    }

    @Override
    public void unfollowee(int userId, int entityType, int entityId) {
        //点击关注的时候 userId用户的关注列表多了一个人
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
        //entityId 用户的粉丝列表多了一个粉丝
        String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);

        redisUtil.multi();

        //将值存进缓存当中
        // 某个用户的关注列表中少了个关注
        redisUtil.zRem(followeeKey, entityId);
        //某个用户的 粉丝少了一个
        redisUtil.zRem(followerKey, userId);

        redisUtil.exec();
    }

    //某个用户的关注列表中的人数
    @Override
    public int focus(int userId, int entityType) {
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);

        return redisUtil.zSize(followeeKey);
    }

    //某个用户的粉丝数
    @Override
    public int followers(int entityType, int entityId) {
        String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);

        return redisUtil.zSize(followerKey);
    }

    /**
     * @param
     * @Description 查询某个用户是否已经关注了
     * @retuen boolean
     * @author wyj
     * @since 2022/7/29 11:02
     */
    @Override
    public boolean isFocus(int userId, int entityType, int entityId) {
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
        boolean haveKV = redisUtil.isZsetHaveKV(followeeKey, entityId);
        return haveKV;
    }


    /**
    * @Description  求取某个用户的
    * @param  userId, entityType, offset, limit]
    * @retuen java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
    * @author wyj
    * @since  2022/7/29 21:35

    */
    @Override
    public List<Map<String, Object>> getFollowees(int userId, int entityType, int offset, int limit) {

        List<Map<String, Object>> list = new ArrayList<>();


        //求出key对应的所有 value 值 也就是关注列表中的 id 数
        String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
        //第一次 从 0 开始  到 下标4结束
        //第二次从 5开始 到 下标结束
        Set<Object> set = redisUtil.zRange(followeeKey, offset, offset + limit - 1);

        if (set != null) {
            for (Object o : set) {

                Map<String, Object> map = new HashMap<>();

                Integer id = (Integer) o;
                //根据关注列表中用户的id 求出关注者
                User user = userServiceImp.getUserById(id);
                //被关注的时间
                Double aDouble = redisUtil.ZsetTime(followeeKey, o);
                //是否被关注  就是查看对应的key 是否有value
                boolean zsetHaveKV = redisUtil.isZsetHaveKV(followeeKey, o);

                map.put("focus", user);
                map.put("FocusTime", new Date(aDouble.longValue()));
                map.put("isFocus", zsetHaveKV == true ? 0 : 1);

                //每一个用户对应一个map
                list.add(map);
            }
        }

        return list;
    }

    /**
    * @Description 获取粉丝列表
    * @param  entityType, entityId, offset, limit]
    * @retuen java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
    * @author wyj
    * @since  2022/7/29 22:24
    */
    @Override
    public List<Map<String, Object>> getFollowers(int entityType, int entityId,int offset, int limit) {
        List<Map<String, Object>> list = new ArrayList<>();

        //求出key对应的所有 value 值 也就是关注列表中的 id 数
        String followerKey = RedisKeyUtil.getFollowerKey(entityType ,entityId);
        //第一次 从 0 开始  到 下标4结束
        //第二次从 5开始 到 下标结束
        Set<Object> set = redisUtil.zRange(followerKey, offset, offset + limit - 1);

        if (set != null) {
            for (Object o : set) {

                Map<String, Object> map = new HashMap<>();

                Integer id = (Integer) o;
                //根据关注列表中用户的id 求出关注者
                User user = userServiceImp.getUserById(id);
                //被关注的时间
                Double aDouble = redisUtil.ZsetTime(followerKey, o);
                //是否被关注  就是查看对应的key 是否有value
                boolean zsetHaveKV = redisUtil.isZsetHaveKV(followerKey, o);

                map.put("fans", user);
                map.put("fansTime", new Date(aDouble.longValue()));
                map.put("isFans", zsetHaveKV == true ? 0 : 1);

                //每一个用户对应一个map
                list.add(map);
            }
        }

        return list;
    }


}
